home *** CD-ROM | disk | FTP | other *** search
/ Turnbull China Bikeride / Turnbull China Bikeride - Disc 2.iso / STUTTGART / UTIL / MEMORY / OLD / MEM208SRC / !Memphis / c / spr < prev    next >
Text File  |  1993-09-08  |  5KB  |  187 lines

  1. /*
  2.  * spr.c
  3.  * Part of the !Memphis distribution
  4.  * (c) bdb/nas, 1991-3
  5.  */
  6.  
  7. #include <stdio.h>
  8. #include <stdlib.h>
  9. #include <string.h>
  10. #include "kernel.h"
  11. #include "swis.h"
  12. #include "_swis.h"
  13. #include "sprite.h"
  14. #include "interface.h"
  15. #include "core.h"
  16.  
  17. #include "spr.h"
  18. static int pagesize = 0x8000;
  19. static int deadsize = 0;
  20. static sprite_area *ss;
  21. static int sssize;
  22. static int ssfreeoff;
  23. static int desired = 0;
  24. static SPRITENAME deadname={ "mfsxdeadspr" }; /* Dead sprites names get 1st 4 chars set to this. */
  25. #define DEADMARK (*(int *)&deadname)
  26.  
  27. static void readarea(void)
  28. {
  29.   _swix(OS_ReadDynamicArea,_IN(0)|_OUT(0)|_OUT(1),3,&ss,&sssize);
  30.   ssfreeoff = sssize?ss->freeoff:sizeof(sprite_area);
  31.   _swix(OS_ReadMemMapInfo,_OUT(0),&pagesize);
  32. }
  33.  
  34. /*{{{  */ static _kernel_oserror *growsprites( int grow ) /* ensure extra bytes in sprite area, 0=ok*/
  35. { _kernel_oserror *err;
  36.   readarea();
  37.   grow -= sssize - ssfreeoff;
  38.   if ( grow <= 0 )
  39.     return 0;
  40.   err = _swix(OS_ChangeDynamicArea,_IN(0)|_IN(1),3,-(-grow & ~(pagesize-1)));
  41.   readarea();
  42.   if (err)
  43.     printf("**************Failed to grow sprite area by %d bytes********",-(-grow & ~(pagesize-1)));
  44.   return err;
  45. }
  46. /*}}}  */
  47. /*{{{  */ static _kernel_oserror *shrinksprites( void ) /* Shrink sprite area if possible/desirable*/
  48. { int shrink;
  49.   _kernel_oserror *err;
  50.   readarea();
  51.   desired = ( _kernel_osbyte( 161, 147, 0 ) >> 8 & 0xFF ) * pagesize;
  52.   shrink = sssize - ssfreeoff - desired;
  53.   shrink = -(-shrink&~(pagesize-1));
  54.   if ( shrink <= 0 )
  55.     return NULL;
  56.   err=_swix( OS_ChangeDynamicArea, _IN(0)|_IN(1),3,-shrink);
  57.   readarea();
  58.   return err;
  59. }
  60. /*}}}  */
  61. /*{{{  */ static void deletedeadsprites( void )/**/
  62. { sprite_header *h,*ch;
  63.   int hsize;
  64.   readarea();
  65. if (sssize)
  66. { for ( ch = h = ( sprite_header * )( ( char * )ss + ss->sproff );
  67.         h < ( sprite_header * )( ( char * )ss + ssfreeoff );
  68.         h = ( sprite_header * )( ( char * )h + hsize ) )
  69.   { hsize = h->next;
  70.     if ( ( ( int * )&h->name )[0] != DEADMARK )
  71.     { if (h != ch)
  72.         memmove(ch, h, hsize);
  73.       ch = (sprite_header *)((char *)ch + hsize);
  74.     }
  75.     else
  76.       ss->number--;
  77.   }
  78.   ssfreeoff = ss->freeoff = (char *)ch - (char *)ss;
  79. }
  80. deadsize = 0;
  81. }
  82. /*}}}  */
  83. /*{{{  */ sprite_header *findsprite( SPRITENAME name ) /* find sprite or NULL*/
  84. { sprite_header *h;
  85.   readarea();
  86.  if (sssize)
  87.   for ( h = ( sprite_header * )( ( char * )ss + ss->sproff );
  88.         h < ( sprite_header * )( ( char * )ss + ssfreeoff );
  89.         h = ( sprite_header * )( ( char * )h + h->next ) )
  90.     if ( ( ( int * )&name )[0]==( ( int * )&h->name )[0] &&
  91.          ( ( int * )&name )[1]==( ( int * )&h->name )[1] &&
  92.          ( ( int * )&name )[2]==( ( int * )&h->name )[2] )
  93.       return h;
  94.   return NULL;
  95. }
  96. /*}}}  */
  97. /*{{{  */ _kernel_oserror *createsprite( SPRITENAME name, int size, sprite_header **rh ) /* create sprite */
  98. { sprite_header *h;
  99.   _kernel_oserror *err;
  100.   size = ( size+3 )&~3;
  101.   if (deadsize > 0)
  102.     deletedeadsprites();
  103.   err=growsprites( SHSIZE + size );
  104.   if (err) return err;
  105.   h = ( sprite_header * )( ( char * )ss + ssfreeoff );
  106.   h->next = SHSIZE + size;
  107.   *( SPRITENAME * )&h->name = name;
  108.   h->width = 0;
  109.   h->height = size/4 - 1;
  110.   h->lbit = 0;
  111.   h->rbit = 31;
  112.   h->image = SHSIZE;
  113.   h->mask = SHSIZE;
  114.   h->mode = 18;
  115.   ss->freeoff += h->next;
  116.   ss->number++;
  117.   *rh = h;
  118.   return NULL;
  119. }
  120. /*}}}  */
  121. /*{{{  */ _kernel_oserror *setspritesize( sprite_header *h, int size ) /* set size */
  122. { _kernel_oserror *err;
  123.   int oldsize;
  124. #ifdef DEBUG
  125.   printf( "setspritesize %p %x\n", h, size );
  126. #endif
  127.   if ( !h )
  128.     return NULL;
  129.   oldsize = h->next-SHSIZE;
  130.   size = ( size+3 )&~3;
  131.   if ( size>oldsize )
  132.   { err = growsprites( size-oldsize );
  133.     if (err) return err;
  134.     memmove( ( char * )h + SHSIZE + size,
  135.              ( char * )h + h->next,
  136.              ( char * )ss + ssfreeoff - ( ( char * )h + h->next ) );
  137.     ss->freeoff += size-oldsize;
  138.     h->height = size/4 - 1;
  139.     h->next = SHSIZE + size;
  140.   }
  141.   else
  142.   if ( size + SHSIZE+4 <= oldsize )     /* Room to truncate */
  143.   { h->height = size/4 - 1;
  144.     h->next = SHSIZE + size;
  145.     h = (sprite_header *)((char *)h+h->next);
  146.     size = oldsize - size - SHSIZE;
  147.     h->next = SHSIZE + size;
  148.     *( SPRITENAME * )&h->name = deadname;
  149.     h->width = 0;
  150.     h->height = size/4 - 1;
  151.     h->lbit = 0;
  152.     h->rbit = 31;
  153.     h->image = SHSIZE;
  154.     h->mask = SHSIZE;
  155.     h->mode = 18;
  156.     deletesprite(h);
  157.   } 
  158.   return NULL;
  159. }
  160. /*}}}  */
  161. /*{{{  */ _kernel_oserror *deletesprite( sprite_header *h ) /* mark as dead and maybe deletedead*/
  162. {  if ( !h )
  163.     return NULL;
  164.   ( ( int * )&h->name )[0] = DEADMARK;
  165.   deadsize += h->next;
  166.   if ( sssize - ssfreeoff + deadsize >= pagesize )
  167.   { deletedeadsprites();
  168.     return shrinksprites();
  169.   }
  170.   return NULL;
  171. }
  172. /*}}}  */
  173. _kernel_oserror *spritefreespace( struct freespace *b)
  174. {
  175.   readarea();
  176.   if (deadsize)
  177.     deletedeadsprites();
  178.   if (sssize)
  179.   { b->free = ss->size - ss->freeoff;
  180.     b->biggest = b->free;
  181.     b->size = ss->size;
  182.   }
  183.   else
  184.     b->free = b->biggest = b->size = 0;
  185.   return NULL;
  186. }
  187.